<?php


namespace app\login\service;


use app\common\model\Error;
use app\lib\exception\MysqlErrorException;
use app\login\model\Account;
use app\login\model\AccountAll;
use app\login\model\Sign;
use Driver\Cache\Redis;
use Page\Page;
use think\Exception;

class SignService
{
    private $name; # token里面的name  推广商户名
    private $info_arr; # redis里面的账号信息
    private $sign_arr; # redis里面账号的sign字符串转成的数组
    private $redis_hash_key; # redis_hash_key
    private $user_id; # redis_id
    private $model;

    public function __construct($name)
    {
        $redis_hash_key = config('redis.account').$name;

        $this->model = new Sign();
        $this->name = $name;
        $info_arr = Redis::hget($redis_hash_key);
        if(count($info_arr) ==0){
            $model = new Account();
            $data = $model->updateDataToRedis($name);
            $this->info_arr = $data;
            Redis::hMset($redis_hash_key, $data);
        }
        $this->info_arr = $info_arr;
        $this->redis_hash_key = $redis_hash_key;
    }

    # 根据数组什么是否存在id进行更新或者添加sign
    public function addOrUpdateSign($data)
    {
        # 先判断数组是否有status字段
        array_key_exists('status', $data) ? $data['status'] = 1 : $data['status'] = 0;
        if($data['id'] == "" || $data['id'] == null){
            $result =  $this->addSign($data);
        }else{
            $result = $this->updateSign($data);
        }
        $this->addSignToSet($this->name, $this->info_arr['id']);
        return $result;
    }
    # 添加sign
    private function addSign($data)
    {
        $bool = $this->findSign($data['sign']);
        if($bool == true){
            return [
                'code' => 400,
                'msg' => '标识码已存在'
            ];
        }

        $data['add_time'] = now_time();
        $data['user_id'] = $this->info_arr['id'];
        $data['host_d'] = $this->info_arr['host_d'];
        $data['host_f'] = $this->info_arr['host_f'];
        try{
            $this->model -> create($data);
        }catch (\Exception $e){
            throw new MysqlErrorException([
                'code' => '500',
                'msg' => '服务器错误'
            ]);
        }
        $this->AddSignToMysqlAndRedis($data['sign']);
        return [
            'code' => 200,
            'msg' => '添加成功'
        ];

    }
    # 更新sign
    private function updateSign($data)
    {
        unset($data['sign']);
        $id = $data['id'];
        unset($data['id']);
        $data['update_time'] = now_time();

        try{
            $this->model -> where('sign_id', '=', $id)
            ->update($data);
        }catch (\Exception $e){
            throw new MysqlErrorException([
                'code' => '500',
                'msg' => '服务器错误'
            ]);
        }
        return [
            'code' => 200,
            'msg' => '修改成功'
        ];
    }

    # 查找sign是否存在
    private function findSign($sign)
    {
        $sign_str = $this->info_arr['sign'];
        $bool = $this->signArr($sign_str, $sign);
        return $bool;
    }

    # 把redis里面的sign字符串转成数组
    private function signArr($sign_str, $sign)
    {
        $sign_arr = explode('%', $sign_str);
        $this->sign_arr = $sign_arr;
        $bool = array_search($sign, $sign_arr);
        return $bool;
    }
    # 同步增加redis里面账号sign的值
    private function AddSignToMysqlAndRedis($sign)
    {
         $new_sign_str = ($this->info_arr)['sign'].'%'.$sign;
        try{
            $model = new Account();
            $model->addOrUpdateSign($this->name, $new_sign_str);
            Redis::hset($this->redis_hash_key, 'sign', $new_sign_str);
        }catch (\Exception $e){
            $data = [
                'error_data' => '添加标识码到数据库失败',
                'remarks' => $e->getMessage()
            ];
            Error::addErrorLog($data);
            throw new MysqlErrorException();
        }
    }

    # =============================================================
    # 查找所有的sign
    public function findAll($page, $limit)
    {
        $where = [
            ['user_id', '=', $this->info_arr['id']]
        ];
        $page = new Page($this->model, $page, $limit, [], ['add_time desc'], $where);
        $result = $page->layuiPage();
        return $result;
    }

    # 删除一条记录
    public function delOneSign($id)
    {
        try{
            $sign = $this->model->delOne($id);
            $sign_str = $this->info_arr['sign'];
            $new_sign_str = $this->delSignInRedis($sign, $sign_str);
            $this->delAccountFileSign($new_sign_str);
            Redis::hset($this->redis_hash_key, 'sign', $new_sign_str);
            return [
                'code' => 200
            ];
        }catch (\Exception $e){
            return [
                'code' => 400
            ];
        }
    }
    # 删除redis的sign
    private function delSignInRedis($sign, $sign_str)
    {
        $sign_arr = explode('%', $sign_str);
        $key = array_search($sign, $sign_arr);
        unset($sign_arr[$key]);
        return implode('%', $sign_arr);
    }

    private function delAccountFileSign($sign_str)
    {
        $model = new Account();
        $model->addOrUpdateSign($this->name, $sign_str);
    }

    # 同步所有sign到redis
    private function addSignToSet($name, $id)
    {
        try{
            $model = new Sign();
            $arr = $model->findSignStatus($id);
            $redis_key = config('redis.all_sign').$name;
            Redis::DelKey($redis_key);
            Redis::sAddArr($redis_key, $arr);
        }catch (\Exception $e){

        }
    }
}